package study.alex.resumedb.gae.model;


import com.vaadin.ui.UI;
import org.datanucleus.api.jpa.annotations.Extension;
import study.alex.resumedb.gae.EMF;
import study.alex.resumedb.gae.ResumeDBMaintUI;

import javax.persistence.*;
import javax.persistence.jpa21.Convert;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.GregorianCalendar;

/**
 * Created with IntelliJ IDEA.
 * User: alex
 * Date: 07.11.13
 * Time: 16:44
 * SVN $Id$
 */


@Entity
public class resumeTracker implements Comparable<resumeTracker>, Serializable {

    public static final int CONFIRM_CALL_AFTER = 1;
    public static final int NEXT_CALL_AFTER = 7;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String id;
    private String userId;

//    @ManyToOne (cascade = {CascadeType.PERSIST, CascadeType.MERGE})
//    private Contact employer = null;
    private String employerId;

    @Basic
    @Convert(converter = GregorianCalendarConverter.class)
    private GregorianCalendar sentdate = null;
    @Basic
    @Convert(converter = GregorianCalendarConverter.class)
    private GregorianCalendar lastcall = null;
    @Basic
    @Convert(converter = GregorianCalendarConverter.class)
    private GregorianCalendar nextcall = null;
    @Basic
    @Convert(converter = GregorianCalendarConverter.class)
    private GregorianCalendar checkcall = null;
    @Basic
    @Convert(converter = GregorianCalendarConverter.class)
    private GregorianCalendar dateofinterview = null;

    @ManyToOne (cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Resume resume;

    @Basic
    @Enumerated (EnumType.STRING)
    private resumeStatus status = resumeStatus.UNKNOWN;

    private String comment = "";

    private String vacancyid;

    public void setCheckcall(GregorianCalendar checkcall) {
        this.checkcall = checkcall;
    }

    public resumeTracker(String userId, Contact employer, GregorianCalendar sentDate, GregorianCalendar checkCall, Resume resume) {
        this(userId, employer, sentDate, resume);
        setCheckcall(checkCall);
    }

    public String getId() {
        return id;
    }

    public resumeTracker(String userId, Contact employer, GregorianCalendar sentDate, Resume resume) {

        this.resume = resume;
        this.userId = userId;
        if (sentDate != null) {
            this.sentdate = sentDate;
        }
        else this.sentdate = new GregorianCalendar();
        if (employer != null) {
            this.employerId = employer.getId();
        }

        nextcall = (GregorianCalendar) (sentDate != null ? sentDate.clone() : null);
        checkcall = (GregorianCalendar) (sentDate != null ? sentDate.clone() : null);
        if (nextcall != null) {
            nextcall.add(GregorianCalendar.DAY_OF_MONTH, NEXT_CALL_AFTER);
        }
        if (checkcall != null) {
            checkcall.add(GregorianCalendar.DAY_OF_MONTH, CONFIRM_CALL_AFTER);
        }
        status = resumeStatus.UNCHECKED;
    }

    public String getEmployer() {
        return employerId;
    }

    public GregorianCalendar getLastcall() {
        return lastcall;
    }

    public GregorianCalendar getNextcall() {
        return nextcall;
    }

    public String getNextRegularCallPresentation() {
        if (status == resumeStatus.REJECTED) return status.toString();
        GregorianCalendar dateCall = getNextRegularCall();
        String call =  "";
        if (dateCall != null) call = DateFormat.getDateInstance(DateFormat.SHORT, ((ResumeDBMaintUI)UI.getCurrent()).getUserLocale()).format(dateCall.getTimeInMillis());
        if (status == resumeStatus.ACCEPTED) call = status.toString() + ": " + call;
        return call;
    }

    public GregorianCalendar getNextRegularCall() {
        GregorianCalendar call = null;
        switch (status) {
            case UNCHECKED:
                call = getCheckcall();
                break;
            case CHECKED:
            case DELAYED:
            case RESERVED:
            case UNKNOWN:
            case CONSIDERED:
                GregorianCalendar dateCall = getLastcall();
                if (dateCall != null && dateCall.compareTo(getNextcall()) >= 0) {
                    dateCall.add(GregorianCalendar.DAY_OF_MONTH, NEXT_CALL_AFTER);
                } else dateCall = getNextcall();
                if (dateCall == null) call = getCheckcall();
                else call = dateCall;
                if (call == null) call = new GregorianCalendar();
                break;
            case REJECTED:
                call = null;
                break;
            case ACCEPTED:
                call = getDateofinterview();
                if (call == null) call = new GregorianCalendar();
                break;
        }
        return call;
    }

    public GregorianCalendar getCheckcall() {
        return checkcall;
    }

    public GregorianCalendar getDateofinterview() {
        return dateofinterview;
    }

    public Resume getResume() {
        return resume;
    }

    public void setResume(Resume resume) {
        this.resume = resume;
    }

    public resumeStatus getStatus() {
        return status;
    }

    public void setLastcall(GregorianCalendar lastcall) {
        this.lastcall = lastcall;
    }

    public void setDateofinterview(GregorianCalendar dateofinterview) {
        this.dateofinterview = dateofinterview;
    }

    public void setStatus(resumeStatus status) {
        this.status = status;
    }

    public void setNextcall(GregorianCalendar nextcall) {
        this.nextcall = nextcall;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public GregorianCalendar getSentdate() {
        return sentdate;
    }

    @Override
    public int compareTo(resumeTracker o) {
        return sentdate.compareTo(o.sentdate);
    }
    @Override
    public String toString() {
        return MessageFormat.format(((ResumeDBMaintUI) UI.getCurrent()).getBundle().getString("sent.0"), DateFormat.getDateInstance(DateFormat.SHORT, ((ResumeDBMaintUI) UI.getCurrent()).getUserLocale()).format(this.getSentdate().getTimeInMillis())); // +
    }

    public void setSentdate(GregorianCalendar sentdate) {
        this.sentdate = sentdate;
    }

    public void setEmployer(Contact employer) {
        if (employer != null ) this.employerId = employer.getId();
    }
    public void setEmployer(String employerId) {
        this.employerId = employerId;
    }

    private Vacancy getVacancyEntity(String id) {
        if (id == null || id.isEmpty()) return null;

        EntityManager em = EMF.getEntityManager();

        try {
            Vacancy v = em.find(Vacancy.class, id);
            return v;
        } finally {
            em.close();
        }
    }

    public Vacancy getVacancy() {
        return getVacancyEntity(vacancyid);
    }

    public void setVacancy(Vacancy vacancy) {
        this.vacancyid = vacancy.getId();
    }
}
